package com.shujia.scala

object Demo12Fun {
  def main(args: Array[String]): Unit = {

    /**
     * 面向对象编程
     * 1、以对象作为参数
     * 2、以对象作为返回值
     *
     * 面向函数编程
     * 1、以函数作为参数
     * 2、以函数作为返回值
     *
     */

    def add(i: Int, j: Int): Int = i + j

    println(add(1, 2))

    /**
     * 函数的类型：由参数类型和返回值类型决定的
     * (Int, Int) => Int:add是一个参数为两盒Int，返回值为Int类型的函数
     */
    val f: (Int, Int) => Int = add

    println(f(2, 2))

    println("java")

    //1、以函数作为参数
    //f是一个参数为String返回值为Int类型的函数
    def fun(f: String => Int): Unit = {
      //嗲用f这个函数
      val i: Int = f("java")
      println(i)
    }

    def f1(str: String): Int = {
      str.length
    }

    fun(f1)

    val ints = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
    //对数组中的元素进行处理，每个元素加1
    for (i <- ints.indices) {
      ints(i) = ints(i) + 1
    }
    println(ints.toList)


    //使用函数式编程
    val ints2 = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    //map的作为是对数组中的数据进行处理，返回值一个新的数组
    //通过拆入的函数对数组中的每个元素进行处理

    def fun2(i: Int): Int = {
      println("fun2")
      i * 2
    }

    val newInts = ints2.map(fun2)
    println(newInts)

    //匿名函数:(i: Int) => i * 100
    val strings: List[String] = ints2.map((i: Int) => i.toString + "scala")
    println(strings)

    //简化
    ints2.map((i: Int) => {
      i.toString + "scala"
    })

    //1、{}可以省略
    ints2.map((i: Int) => i.toString + "scala")

    //2、参数类型可以省略,自动推断类型
    ints2.map(i => i.toString + "scala")

    //3、当参数只使用一次时，可以通过下划线代替
    println(ints2.map(_.toString + "2"))

    //循环列表
    ints2.foreach((i: Int) => println(i))
    ints2.foreach(i => println(i))
    ints2.foreach(println(_))
    ints2.foreach(println)
    ints2 foreach println
  }
}
